﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Media.Effects;


namespace AllenalaMente.Games.NewPuzzle
{
    public partial class PuzzlePiece : UserControl
    {
        public double translateX, translateY;
        public bool isFixed;
        public bool PieceRightFinalPosition;
        public bool isBeingDragged;
        private Point mouseOffset;
        public Point finalPosition, actualPos, finalAnimPoint;
        public int Index;
        public Point solPos, iniztialPos;
        int depth;
        List<string> pathStrings;
        Image mainImage;
        public const int borderOffsetX = 100, borderOffsetY = 50;
        public TextBox testRect;

        public PuzzlePiece(int size, int index, string strImg, int Righe, int Colonne )
        {
            InitializeComponent();


            StringToPathGeometryConverter st = new StringToPathGeometryConverter();
            isBeingDragged = false;
            PieceRightFinalPosition = false;
            Index = index;
            pathStrings = new List<string>();

            //pathStrings.Add("M22.5,0.5 C34.650265,0.5 44.5,9.9020205 44.5,21.5 C44.5,28.56752 40.842419,34.819595 35.235527,38.62561 L35.155327,38.67868 L34.88063,39.109314 C28.601402,49.128017 30.320751,55.699516 40.5,58.625 L22.5,58.625 L22.5,58.5 L4.4999995,58.5 C14.679248,55.574516 16.398598,49.003017 10.119369,38.984318 L9.982645,38.769978 L9.7644749,38.62561 C4.1575794,34.819595 0.49999964,28.56752 0.5,21.5 C0.49999964,9.9020205 10.349735,0.5 22.5,0.5 z");
            //pathStrings.Add("M0,0 L80,0.5 L80,80 L0,80 z");
            pathStrings.Add("M0,0 L"+size+",0 L"+size+","+size+" L0,"+size+" z");

            // Inizializzo immagine puzzle
            mainImage = new Image();
            Uri uri = new Uri(strImg, UriKind.Relative);
            mainImage.Source = new System.Windows.Media.Imaging.BitmapImage(uri);
            mainImage.Width = size * Righe;
            mainImage.Height = size * Colonne;
            mainImage.Stretch = Stretch.Fill;


            // Inizializzo l'immagine per ombra/spessore
            //Image shadowImg = new Image();
            //string strImg2 = "/Minigames;component/Assets/blackCover.png";
            //Uri uri2 = new Uri(strImg2, UriKind.Relative);
            //shadowImg.Source = new System.Windows.Media.Imaging.BitmapImage(uri2);
            //shadowImg.Width = size * COLUMNS;
            //shadowImg.Height = size * COLUMNS;

            // Inizializzo le group geometries
            GeometryGroup geoGroupMainImg = new GeometryGroup();

            PathGeometry baserect = st.Convert(pathStrings[0]);
            //PathGeometry baserectShadow = st.Convert(pathStrings[1]);
            geoGroupMainImg.Children.Add(baserect);
            //geoGroupShadowImg.Children.Add(baserectShadow);

            // In base all'array di interi mi costruisco il pezzo principale
            //if (pSides[0] != 2)
            //    geoGroupMainImg.Children.Add(generatePattern(pSides[0], 1));
            //if (pSides[1] != 2)
            //    geoGroupMainImg.Children.Add(generatePattern(pSides[1], 2));
            //if (pSides[2] != 2)
            //    geoGroupMainImg.Children.Add(generatePattern(pSides[2], 3));
            //if (pSides[3] != 2)
            //    geoGroupMainImg.Children.Add(generatePattern(pSides[3], 4));

            //// In base all'array di interi mi costruisco il pezzo ombra
            //if (pSides[0] != 2)
            //    geoGroupShadowImg.Children.Add(generatePattern(pSides[0], 1));
            //if (pSides[1] != 2)
            //    geoGroupShadowImg.Children.Add(generatePattern(pSides[1], 2));
            //if (pSides[2] != 2)
            //    geoGroupShadowImg.Children.Add(generatePattern(pSides[2], 3));
            //if (pSides[3] != 2)
            //    geoGroupShadowImg.Children.Add(generatePattern(pSides[3], 4));

            // Applico la translazione per ritagliare l'immagine 
            translateX = size * (Index % Righe);
            translateY = size * (Index / Colonne);
            geoGroupMainImg.Transform = new CompositeTransform() { TranslateX = translateX, TranslateY = translateY };

            // Applico i clip alle immagini
            mainImage.Clip = geoGroupMainImg;
            //shadowImg.Clip = geoGroupShadowImg;

            // Creo il rettangolo soluzione per il singolo pezzo
            //solPos.X = borderOffsetX + (size * (Index % COLUMNS));
            //solPos.Y = borderOffsetY + (size * (Index / COLUMNS));

            // Remposto il pezzo traslato nel canvas
            //iniztialPos.X = Canvas.GetLeft(mainImage);
            //iniztialPos.Y = Canvas.GetTop(mainImage);
            //Canvas.SetLeft(mainImage, -2 - (size * (Index % COLUMNS)));
            //Canvas.SetTop(mainImage, -2 - (size * (Index / COLUMNS)));

            // Eventi
            //mainImage.MouseLeftButtonDown += new MouseButtonEventHandler(img1_MouseLeftButtonDown);
            //mainImage.MouseLeftButtonUp += new MouseButtonEventHandler(img1_MouseLeftButtonUp);

            //CompletePiece.Children.Add(shadowImg);
            CompletePiece.Children.Add(mainImage);

            // test rect
            //testRect.Text = Canvas.GetLeft(mainImage).ToString() + " " + Canvas.GetTop(mainImage).ToString() + "\n" + (size * (Index % COLUMNS)) + " " + (size * (Index / COLUMNS));

            // Salvo la depth del pezzo per creare effetto depth
            //depth = Canvas.GetZIndex(this);
            //rectangle1.Visibility = Visibility.Collapsed;

        }

        public void setPosition(Point p)
        {
            actualPos.X = p.X;
            actualPos.Y = p.Y;
        }

        public void Move(int FromX, int FromY, int ToX, int ToY)
        {

            EasingFunctionBase[] ef = new EasingFunctionBase[]{
        new BackEase(),
        new BounceEase(),
        new CircleEase(),
        new CubicEase(),
        new ElasticEase(),
        new ExponentialEase(),
        new PowerEase(),
        new QuadraticEase(),
        new QuarticEase(),
        new QuinticEase(),
        new SineEase()
      };

            int eFindex = new Random().Next(0, ef.Count());
            int eFindex2 = new Random().Next(0, ef.Count());

            // ef[eFindex].EasingMode = EasingMode.EaseIn;
            // ef[eFindex].EasingMode = EasingMode.EaseOut;
            ef[eFindex].EasingMode = EasingMode.EaseInOut;

            DoubleAnimation doubleAnimationY = new DoubleAnimation()
            {
                Duration = new Duration(TimeSpan.FromSeconds(1)),
                EasingFunction = ef[eFindex]
            };

            DoubleAnimation doubleAnimationX = new DoubleAnimation()
            {
                Duration = new Duration(TimeSpan.FromSeconds(1)),
                EasingFunction = ef[eFindex2]
            };

            Storyboard sb = new Storyboard();

            CompletePiece.RenderTransform = new TranslateTransform();

            doubleAnimationY.From = FromY;
            doubleAnimationY.To = ToY;

            doubleAnimationX.From = FromX;
            doubleAnimationX.To = ToX;

            Storyboard.SetTargetProperty(doubleAnimationY, new PropertyPath("(UIElement.RenderTransform).(TranslateTransform.Y)"));
            Storyboard.SetTargetProperty(doubleAnimationX, new PropertyPath("(UIElement.RenderTransform).(TranslateTransform.X)"));

            Storyboard.SetTarget(doubleAnimationY, CompletePiece);
            Storyboard.SetTarget(doubleAnimationX, CompletePiece);

            sb.Children.Add(doubleAnimationY);
            sb.Children.Add(doubleAnimationX);

            sb.Completed += new EventHandler(sb_Completed);
            sb.Begin();

            finalAnimPoint = new Point(ToX, ToY);
        }

        private void sb_Completed(object sender, EventArgs e)
        {
            // reimposto lo spot per la soluzione in base all'animazione
            solPos.X = solPos.X - finalAnimPoint.X;
            solPos.Y = solPos.Y - finalAnimPoint.Y;
        }

        private PathGeometry generatePattern(int side, int piecePos)
        {
            if (side == 0)
            {
                StringToPathGeometryConverter st = new StringToPathGeometryConverter();
                PathGeometry pg = new PathGeometry();
                switch (piecePos)
                {
                    case 1:
                        pg = st.Convert(pathStrings[0]);
                        pg.Transform = new CompositeTransform() { Rotation = 270, CenterX = 65, CenterY = 23, ScaleX = 0.4, ScaleY = 0.4 };
                        break;
                    case 2:
                        pg = st.Convert(pathStrings[0]);
                        pg.Transform = new CompositeTransform() { Rotation = 0, CenterX = 50, CenterY = 93, ScaleX = 0.4, ScaleY = 0.4 };
                        break;
                    case 3:
                        pg = st.Convert(pathStrings[0]);
                        pg.Transform = new CompositeTransform() { Rotation = 90, CenterX = 10, CenterY = 35, ScaleX = 0.4, ScaleY = 0.4 };
                        break;
                    case 4:
                        pg = st.Convert(pathStrings[0]);
                        pg.Transform = new CompositeTransform() { Rotation = 180, CenterX = 34, CenterY = 17, ScaleY = 0.4, ScaleX = 0.4 };
                        break;
                }
                return pg;
            }
            else
            {
                StringToPathGeometryConverter st2 = new StringToPathGeometryConverter();
                PathGeometry pg = new PathGeometry();
                switch (piecePos)
                {
                    case 1:
                        pg = st2.Convert(pathStrings[0]);
                        pg.Transform = new CompositeTransform() { Rotation = 90, CenterX = 78, CenterY = 63, ScaleX = 0.4, ScaleY = 0.4 };
                        break;
                    case 2:
                        pg = st2.Convert(pathStrings[0]);
                        pg.Transform = new CompositeTransform() { Rotation = 180, CenterX = 35, CenterY = 73, ScaleX = 0.4, ScaleY = 0.4 };
                        break;
                    case 3:
                        pg = st2.Convert(pathStrings[0]);
                        pg.Transform = new CompositeTransform() { Rotation = 270, CenterX = -3, CenterY = 50, ScaleX = 0.4, ScaleY = 0.4 };
                        break;
                    case 4:
                        pg = st2.Convert(pathStrings[0]);
                        pg.Transform = new CompositeTransform() { Rotation = 0, CenterX = 50, CenterY = -39, ScaleY = 0.4, ScaleX = 0.4 };
                        break;
                }
                return pg;
            }

        }

        //public void img1_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        //{
        //    // inizia il trascinamento
        //    isBeingDragged = true;
        //    mouseOffset = e.GetPosition(this);
        //    Canvas.SetZIndex(this, 100);
        //    rectangle1.Visibility = Visibility.Visible;

        //    e.Handled = true;



        //}

        //public void img1_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        //{
        //    // se il pezzo è nella posizione giusta lo "incastra"
        //    //if (checkPos(actualPos))
        //    //{
        //    //    Canvas.SetLeft(this, solPos.X);
        //    //    Canvas.SetTop(this, solPos.Y);
        //    //    PieceRightFinalPosition = true;
        //    //}
        //    //else
        //    //    PieceRightFinalPosition = false;

        //    // reimposto le depth
        //    Canvas.SetZIndex(this, depth + 10);
        //    rectangle1.Visibility = Visibility.Collapsed;
        //}


        //public void UpdatePosition(Point mousePosition)
        //{
        //    var newPosition = new Point();
        //    newPosition.X = mousePosition.X - mouseOffset.X;
        //    newPosition.Y = mousePosition.Y - mouseOffset.Y;
        //    Canvas.SetLeft(this, newPosition.X);
        //    Canvas.SetTop(this, newPosition.Y);

        //    testRect.Text = Index.ToString() + "\n " + actualPos.X.ToString() + "\n" + actualPos.Y.ToString() + "\n";
        //}

        //private bool checkPos(Point p)
        //{
        //    // Controllo se il pezzo è nel range giusto
        //    if ((solPos.X > p.X - 7 && solPos.X < p.X + 7) && (solPos.Y > p.Y - 7 && solPos.Y < p.Y + 7))
        //        return true;
        //    else
        //        return false;
        //}


    }
}


//string nonColour = "Polkadot";
//int ab = 0;
//if (Enum.IsDefined(typeof(pstrings), prova))
//  ab = (int)Enum.Parse(typeof(pstrings), prova, true);
//else
//  ab = 0;
//Canvas.SetLeft(img1, 200);
//Canvas.SetTop(img1, 100);
//img1.Clip.Transform = new CompositeTransform() {  SkewX = 80 };// = gg;
//gg.Transform = new CompositeTransform() { TranslateX = 180 };
//img1.Clip = gg;

//st = new StringToPathGeometryConverter();
//pg = st.Convert(str);
//path = new Path();
//path.Data = pg;
//path.Height = 80;
//path.Width = 80;
//path.Stroke = new SolidColorBrush(Colors.Black);
//path.Fill = new SolidColorBrush(Colors.Black);
//path.RenderTransform = new CompositeTransform() { CenterX = path.Height / 2, CenterY = path.Width / 2, Rotation = 180 };
//Canvas.SetLeft(path, 10);
//Canvas.SetTop(path, 10);
//LayoutRoot.Children.Add(path);

//if (pSides[0] != 2)
// gg.Children.Add(generatePattern(path, path1 = new Path(), 1, pSides[0]));
//if (pSides[1] != 2)
//  gg.Children.Add(generatePattern(path, path2 = new Path(), 2, pSides[1]));
//if (pSides[2] != 2)
//  gg.Children.Add(generatePattern(path, path3 = new Path(), 3, pSides[2]));
//if (pSides[3] != 2)
//  gg.Children.Add(generatePattern(path, path4 = new Path(), 4, pSides[3]));

//PathFigure clipPathFigure = new PathFigure();
//PathFigureCollection clipPathFigureCollection = new PathFigureCollection();

//clipPathFigureCollection.Add(pathGeometry.Figures[0]);

//PathGeometry clipPathGeometry = new PathGeometry();
//clipPathGeometry.Figures = pathGeometry.Figures;

//clipPath = pathStrings[ab];



//Rectangle r1 = new Rectangle() { Width = 50, Height = 50, Stroke = new SolidColorBrush(Colors.Black) };
//Ellipse e1 = new Ellipse() { Width = 30, Height = 30, Stroke = new SolidColorBrush(Colors.Red) };
//GeometryCollection gc = new GeometryCollection();
//GeometryGroup gg = new GeometryGroup();